home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / DDJ0192.ARJ / L5.C < prev    next >
Text File  |  1991-10-01  |  5KB  |  121 lines

  1. /* Simple 3D drawing program to view a polygon as it rotates in
  2.    mode X. View space is congruent with world space, with the
  3.    viewpoint fixed at the origin (0,0,0) of world space, looking in
  4.    the direction of increasingly negative Z. A right-handed
  5.    coordinate system is used throughout.
  6.    Tested with Borland C++ 2.0 in the small model */
  7. #include <conio.h>
  8. #include <stdio.h>
  9. #include <dos.h>
  10. #include <math.h>
  11. #include "polygon.h"
  12. void main(void);
  13.  
  14. /* Base offset of page to which to draw */
  15. unsigned int CurrentPageBase = 0;
  16. /* Clip rectangle; clips to the screen */
  17. int ClipMinX=0, ClipMinY=0;
  18. int ClipMaxX=SCREEN_WIDTH, ClipMaxY=SCREEN_HEIGHT;
  19. /* Rectangle specifying extent to be erased in each page */
  20. struct Rect EraseRect[2] = { {0, 0, SCREEN_WIDTH, SCREEN_HEIGHT},
  21.    {0, 0, SCREEN_WIDTH, SCREEN_HEIGHT} };
  22. /* Transformation from polygon's object space to world space.
  23.    Initially set up to perform no rotation and to move the polygon
  24.    into world space -140 units away from the origin down the Z axis.
  25.    Given the viewing point, -140 down the Z axis means 140 units away
  26.    straight ahead in the direction of view. The program dynamically
  27.    changes the rotation and translation */
  28. static double PolyWorldXform[4][4] = {
  29.    {1.0, 0.0, 0.0, 0.0},
  30.    {0.0, 1.0, 0.0, 0.0},
  31.    {0.0, 0.0, 1.0, -140.0},
  32.    {0.0, 0.0, 0.0, 1.0} };
  33. /* Transformation from world space into view space. In this program,
  34.    the view point is fixed at the origin of world space, looking down
  35.    the Z axis in the direction of increasingly negative Z, so view
  36.    space is identical to world space; this is the identity matrix */
  37. static double WorldViewXform[4][4] = {
  38.    {1.0, 0.0, 0.0, 0.0},
  39.    {0.0, 1.0, 0.0, 0.0},
  40.    {0.0, 0.0, 1.0, 0.0},
  41.    {0.0, 0.0, 0.0, 1.0}
  42. };
  43. static unsigned int PageStartOffsets[2] =
  44.    {PAGE0_START_OFFSET,PAGE1_START_OFFSET};
  45. int DisplayedPage, NonDisplayedPage;
  46.  
  47. void main() {
  48.    int Done = 0;
  49.    double WorkingXform[4][4];
  50.    static struct Point3 TestPoly[] =
  51.          {{-30,-15,0,1},{0,15,0,1},{10,-5,0,1}};
  52. #define TEST_POLY_LENGTH   (sizeof(TestPoly)/sizeof(struct Point3))
  53.    double Rotation = M_PI / 60.0; /* initial rotation = 3 degrees */
  54.    union REGS regset;
  55.  
  56.    Set320x240Mode();
  57.    ShowPage(PageStartOffsets[DisplayedPage = 0]);
  58.    /* Keep rotating the polygon, drawing it to the undisplayed page,
  59.       and flipping the page to show it */
  60.    do {
  61.       CurrentPageBase =    /* select other page for drawing to */
  62.             PageStartOffsets[NonDisplayedPage = DisplayedPage ^ 1];
  63.       /* Modify the object space to world space transformation matrix
  64.          for the current rotation around the Y axis */
  65.       PolyWorldXform[0][0] = PolyWorldXform[2][2] = cos(Rotation);
  66.       PolyWorldXform[2][0] = -(PolyWorldXform[0][2] = sin(Rotation));
  67.       /* Concatenate the object-to-world and world-to-view
  68.          transformations to make a transformation matrix that will
  69.          convert vertices from object space to view space in a single
  70.          operation */
  71.       ConcatXforms(WorldViewXform, PolyWorldXform, WorkingXform);
  72.       /* Clear the portion of the non-displayed page that was drawn
  73.          to last time, then reset the erase extent */
  74.       FillRectangleX(EraseRect[NonDisplayedPage].Left,
  75.             EraseRect[NonDisplayedPage].Top,
  76.             EraseRect[NonDisplayedPage].Right,
  77.             EraseRect[NonDisplayedPage].Bottom, CurrentPageBase, 0);
  78.       EraseRect[NonDisplayedPage].Left =
  79.             EraseRect[NonDisplayedPage].Top = 0x7FFF;
  80.       EraseRect[NonDisplayedPage].Right =
  81.          EraseRect[NonDisplayedPage].Bottom = 0;
  82.       /* Transform the polygon, project it on the screen, draw it */
  83.       XformAndProjectPoly(WorkingXform, TestPoly, TEST_POLY_LENGTH,9);
  84.       /* Flip to display the page into which we just drew */
  85.       ShowPage(PageStartOffsets[DisplayedPage = NonDisplayedPage]);
  86.       /* Rotate 6 degrees farther around the Y axis */
  87.       if ((Rotation += (M_PI/30.0)) >= (M_PI*2)) Rotation -= M_PI*2;
  88.       if (kbhit()) {
  89.          switch (getch()) {
  90.             case 0x1B:     /* Esc to exit */
  91.                Done = 1; break;
  92.             case 'A': case 'a':      /* away (-Z) */
  93.                PolyWorldXform[2][3] -= 3.0; break;
  94.             case 'T':      /* towards (+Z). Don't allow to get too */
  95.             case 't':      /* close, so Z clipping isn't needed */
  96.                if (PolyWorldXform[2][3] < -40.0)
  97.                      PolyWorldXform[2][3] += 3.0; break;
  98.             case 0:     /* extended code */
  99.                switch (getch()) {
  100.                   case 0x4B:  /* left (-X) */
  101.                      PolyWorldXform[0][3] -= 3.0; break;
  102.                   case 0x4D:  /* right (+X) */
  103.                      PolyWorldXform[0][3] += 3.0; break;
  104.                   case 0x48:  /* up (+Y) */
  105.                      PolyWorldXform[1][3] += 3.0; break;
  106.                   case 0x50:  /* down (-Y) */
  107.                      PolyWorldXform[1][3] -= 3.0; break;
  108.                   default:
  109.                      break;
  110.                }
  111.                break;
  112.             default:       /* any other key to pause */
  113.                getch(); break;
  114.          }
  115.       }
  116.    } while (!Done);
  117.    /* Return to text mode and exit */
  118.    regset.x.ax = 0x0003;   /* AL = 3 selects 80x25 text mode */
  119.    int86(0x10, ®set, ®set);
  120. }
  121.